// HTable.cpp : 定义控制台应用程序的入口点。
//

#include <string>
#include <vector>
#include <set>
#include <core/sync/lock.h>
#include "DataBase.h"
#include "QuotaMap.h"
//#include "Grid.h"
#include "Table.h"
#include "TableUser.h"
#include "TableWriter.h"

using namespace std;

#ifdef WIN32
#include <windows.h>
#define BASSERT assert
#else
#define BASSERT //
#endif

namespace qb{
	namespace ht{
		static DataBase* gs_table = 0;
        static qb::base::CSLock  gs_table_lock;
		void DataBase::Release()
		{
			if (gs_table)
			{
				SCOPED_LOCK(gs_table_lock);
				if (gs_table)
					delete gs_table;
				gs_table = 0;
			}
		}
        qb::ht::DataBase& DataBase::Get()
		{
			if (gs_table == 0)
			{
				SCOPED_LOCK(gs_table_lock);
				if (gs_table == 0)
				{
					gs_table = new DataBase();
				}
			}
			return *gs_table;
		}

		DataBase::DataBase()
		{

		}

		DataBase::~DataBase()
		{
			TableMap::iterator it = m_tablemap.begin();
			for (; it != m_tablemap.end(); ++it)
			{
				Table* tb = it->second;
				delete tb;
			}
			m_tablemap.clear();
		}

		//	class NotifyQueue{
		//	public:
		//		void Clear(){}
		//		Grid* GetGrid(){ return 0; }
		//		void AddMessage(){}
		//	};
		//	typedef map<HWND, NotifyQueue> NotifyQueueMap;
		//	NotifyQueueMap m_notify_queue_map;
		//public:
		//	void AddNotifier(Grid* grid)
		//	{
		//		HWND wnd = grid->GetWindow();
		//		m_notify_queue_map[wnd] = NotifyQueue();
		//	}
		//	void RemoveNotifier(HWND wnd)
		//	{
		//		NotifyQueueMap::iterator it = m_notify_queue_map.find(wnd);
		//		m_notify_queue_map.erase(it);
		//	}
		//	void OnTableNotify(HWND wnd)
		//	{
		//		NotifyQueueMap::iterator it = m_notify_queue_map.find(wnd);
		//		NotifyQueue& queue = it->second;
		//		queue.AddMessage();
		//	}
		//	void OnRefreshTimer()
		//	{
		//		NotifyQueueMap::iterator it = m_notify_queue_map.begin();
		//		for (; it != m_notify_queue_map.begin(); ++it)
		//		{
		//			NotifyQueue& queue = it->second;
		//			queue.Clear();
		//			Grid* grid = queue.GetGrid();
		//			grid->OnTableUpdated();
		//		}
		//	}
		//};

		bool DataBase::CreateTable(const TableDesc& desc, int tableid, const char* name, bool useldb)
		{
			//Table* table = new Table(desc, GetNextTableId());
			//writer->SetTable(table);
			//table->AddUser(user);
			//return table->GetTableId();
			
            BASSERT(tableid > 0 && m_tablemap.find(tableid) == m_tablemap.end());
			Table* table = new Table(desc, tableid, desc.GetRecordSize(), useldb);
			if (name)
				table->SetName(name);
			table->Initialize(name);
			table->GetCache();
			m_tablemap[tableid] = table;
			return true;
		}
		bool DataBase::RemoveTable(int id)
		{
			TableMap::iterator it = m_tablemap.find(id);
			if (it != m_tablemap.end())
			{
				delete it->second;
				m_tablemap.erase(it);
				return true;
			}
			return false;
		}
		bool DataBase::RegisterUser(TableUser* user, int tableid)
		{
			Table* table = GetTable(tableid);
            BASSERT(table && user);
			table->AddUser(user);
			return true;
		}

		Table* DataBase::GetTable(int tableid)
		{
			TableMap::iterator it = m_tablemap.find(tableid);
			return it != m_tablemap.end() ? it->second : 0;
		}

        void DataBase::OnNetMessage(int funcid, void* wparam, void* lparam)
		{
			WriterListMap::iterator mit = m_writers.find(funcid);
			if (mit != m_writers.end())
			{
				WriterList& writerlist = mit->second;
				WriterList::iterator lit = writerlist.begin();
				for (; lit != writerlist.end(); ++lit)
				{
					TableWriter* writer = *lit;
					writer->OnNetMessage(funcid, wparam, lparam);
				}
			}
		}

        void DataBase::NotifyGrid(void* grid)
		{
			//m_window->OnTableNotify(grid);
		}



		//void DataBase::RegisterGrid(Grid* grid)
		//{
		//	//m_window->AddNotifier(grid);
		//}
	}//namespace ht
}//namespace qb
